home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 January: Mac OS SDK / Dev.CD Jan 98 SDK1.toast / Development Kits (Disc 1) / QuickDraw 3D / Samples / SampleCode / 3DMF2PICT / 3DMF2PICTShell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-14  |  12.4 KB  |  498 lines  |  [TEXT/CWIE]

  1. // Quickdraw 3D sample code
  2. //
  3. // Nick Thompson, AppleLink: DEVSUPPORT (devsupport@applelink.apple.com)
  4. //
  5. // ©1994-5 Apple Computer Inc., All Rights Reserved
  6.  
  7.  
  8. // system headers
  9. #include <Devices.h>
  10. #include <Dialogs.h>
  11. #include <DiskInit.h>
  12. #include <Fonts.h>
  13. #include <Menus.h>
  14. #include <PictUtils.h>
  15. #include <QDOffScreen.h>
  16. #include <QuickDraw.h>
  17. #include <SegLoad.h>
  18. #include <StandardFile.h>
  19. #include <TextEdit.h>
  20. #include <ToolUtils.h>
  21.  
  22. // for QuickDraw 3D
  23. #include "QD3D.h"
  24. #include "QD3DMath.h"
  25. #include "QD3DDrawContext.h"
  26. #include "QD3DShader.h"
  27. #include "QD3DTransform.h"
  28. #include "QD3DGroup.h"
  29. #include "QD3DCamera.h"
  30.  
  31.  
  32. #include "3DMF2PICTShell.h"
  33. #include "3DMF2PICTSupport.h"
  34.  
  35. // get the interface to my error handler routines
  36. #include "MyErrorHandler.h"
  37.  
  38.  
  39. //-------------------------------------------------------------------------------------------
  40. // function prototypes
  41.  
  42. static void         InitToolbox( void ) ;
  43. static void         MainEventLoop( void ) ;
  44. static void         HandleKeyPress(EventRecord *event) ;
  45. static void         HandleOSEvent(EventRecord *event) ;
  46. void InitDocumentData( DocumentPtr theDocument ) ;
  47. TQ3Status DocumentDraw3DData( DocumentPtr theDocument ) ;
  48. void DisposeDocumentData( DocumentPtr theDocument) ;
  49. void DocumentDrawOnscreen(DocumentPtr theDocument, Rect *clipRect) ;
  50.  
  51. OSErr WritePict( PicHandle myPic, short  dstPictFRef ) ;
  52. OSErr GetOutputFileRef(short    *dstPictFRef ) ;
  53. PicHandle ImageToPict( DocumentPtr theDocument, WindowPtr theWindow ) ;
  54. void DoSaveAs(DocumentPtr theDocument)  ;
  55.  
  56. //-------------------------------------------------------------------------------------------
  57. //
  58.  
  59. Boolean         gQuitFlag         = false ;
  60. WindowPtr        gMainWindow        = nil ;
  61. DocumentRec        gDocument ;
  62.  
  63. //-------------------------------------------------------------------------------------------
  64. // main()
  65. // entry point for the application, initialize the toolbox, initialize QuickDraw 3D
  66. // and enter the main event loop.  On exit from the main event loop, we want to call
  67. // the QuickDraw 3D exit function to clean up QuickDraw 3d.
  68.  
  69. void main(void)
  70. {
  71.     TQ3Status    myStatus;
  72.     Rect        rBounds = { 50, 50, 350, 350 } ;
  73.     Str255        title = "\pSpinning Box" ;
  74.     FSSpec        theFileSpec ;                // the file we are opening
  75.  
  76.     InitToolbox() ;
  77.  
  78.     if(MetafileFileSpecify( &theFileSpec )) {
  79.     
  80.         SetCursor(*(GetCursor(watchCursor)));
  81.         
  82.         //    Initialize QuickDraw 3D, open a connection to the QuickDraw 3D library
  83.         myStatus = Q3Initialize();
  84.         if ( myStatus == kQ3Failure )
  85.             DebugStr("\pErInitialize returned failure.");            
  86.     
  87.         // install the error & warning handler - these get called whenever
  88.         // errors or warnings occur, which means we don't have to check so 
  89.         // much
  90.         Q3Error_Register( MyErrorHandler, 0L );        
  91.         Q3Warning_Register( MyWarningHandler, 0L );        
  92.     
  93.         // set up our globals
  94.         gQuitFlag = false ;
  95.         gMainWindow = NewCWindow(nil,&rBounds,title,false,noGrowDocProc,(WindowPtr)-1,true,0) ;
  96.  
  97.         // initialise our document structure
  98.         InitDocumentData( &gDocument ) ;
  99.         
  100.         // try to read the file into the main display group
  101.         if((gDocument.fModel = MyNewModelFromFile(&theFileSpec)) != NULL ) {        
  102.  
  103.             AdjustCamera(    &gDocument,
  104.                             (gMainWindow->portRect.right - gMainWindow->portRect.left),
  105.                             (gMainWindow->portRect.bottom - gMainWindow->portRect.top) ) ;
  106.  
  107.             SetWTitle( gMainWindow, theFileSpec.name );
  108.             ShowWindow( gMainWindow ) ;
  109.             SetPort( gMainWindow ) ;
  110.     
  111.             SetCursor(&qd.arrow) ;
  112.             MainEventLoop();
  113.             
  114.         }
  115.                 
  116.         DisposeDocumentData( &gDocument ) ;
  117.         
  118.         //    Close our connection to the QuickDraw 3D library
  119.         myStatus = Q3Exit();
  120.         if ( myStatus == kQ3Failure )
  121.             DebugStr("\pErExit returned failure.");
  122.     }    
  123. }
  124.  
  125. //-------------------------------------------------------------------------------------------
  126. //
  127.  
  128. void InitDocumentData( DocumentPtr theDocument ) 
  129. {
  130.     GWorldPtr        theOffscreen ;
  131.     GDHandle        theDevice ;
  132.     TQ3Point3D        myOrigin = { 0, 0, 0 } ;
  133.     
  134.     // create a GWorld the size of the window area
  135.     OSErr myErr = NewGWorld(    &theDocument->fGWorld,
  136.                                 32,
  137.                                 &gMainWindow->portRect,
  138.                                 nil,
  139.                                 nil,
  140.                                 0L );
  141.     
  142.     if(myErr != noErr )
  143.         goto bail ;
  144.         
  145.     GetGWorld( &theOffscreen, &theDevice ) ;
  146.     SetGWorld( theDocument->fGWorld, nil ) ;
  147.     EraseRect( &gMainWindow->portRect ) ;
  148.     SetGWorld( theOffscreen, theDevice ) ;
  149.     
  150.     // sets up the 3d data for the scene
  151.     //    Create view for QuickDraw 3D.
  152.     theDocument->fView = MyNewView( theDocument->fGWorld );
  153.  
  154.     // the main display group:
  155.     theDocument->fModel = NULL ;
  156.     
  157.     // scale and group center
  158.     theDocument->fGroupScale = 1;                
  159.     theDocument->fGroupCenter = myOrigin ;    
  160.     
  161.     // the drawing styles:
  162.     theDocument->fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleNone) ;
  163.     theDocument->fBackFacing = Q3BackfacingStyle_New( kQ3BackfacingStyleBoth ) ;
  164.     theDocument->fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ;
  165.  
  166.     // set the rotation matrix the identity matrix
  167.     Q3Matrix4x4_SetIdentity(&theDocument->fRotation);    
  168.                     
  169.     return ;
  170.     
  171. bail:
  172.     // we failed setting up the GWorld
  173.     // so we want to quit here
  174.     ExitToShell() ;
  175.     
  176. }
  177.  
  178. void DisposeDocumentData( DocumentPtr theDocument)
  179. {
  180.     Q3Object_Dispose(theDocument->fView) ;                // the view for the scene
  181.     Q3Object_Dispose(theDocument->fModel) ;                // object in the scene being modelled
  182.     Q3Object_Dispose(theDocument->fInterpolation) ;        // interpolation style used when rendering
  183.     Q3Object_Dispose(theDocument->fBackFacing) ;        // whether to draw shapes that face away from the camera
  184.     Q3Object_Dispose(theDocument->fFillStyle) ;            // whether drawn as solid filled object or decomposed to components
  185. }
  186. //-----------------------------------------------------------------------------
  187. // assumes the port is set up before being called
  188.  
  189. TQ3Status DocumentDraw3DData( DocumentPtr theDocument )
  190. {    
  191.     TQ3Status theStatus ;    
  192. //{
  193. //    TQ3CameraData        theCameraData ;
  194. //    TQ3CameraObject        theCameraObject;
  195. //    
  196. //    Q3View_GetCamera(theDocument->fView, &theCameraObject);
  197. //    Q3Camera_GetData(theCameraObject, &theCameraData);
  198. //Debugger() ;
  199. //
  200. //}
  201.  
  202.     //    Start rendering.
  203.     Q3View_StartRendering(theDocument->fView) ;
  204.     do {
  205.         theStatus = SubmitScene( theDocument ) ;
  206.     } while (Q3View_EndRendering(theDocument->fView) == kQ3ViewStatusRetraverse );
  207.  
  208.     return theStatus ;    
  209. }
  210.  
  211. //-------------------------------------------------------------------------------------------
  212. //
  213.  
  214. void DocumentDrawOnscreen(DocumentPtr theDocument, Rect *clipRect)
  215. {
  216.     if (theDocument->fGWorld) {
  217.     
  218.         CGrafPtr            savedPort;
  219.         GDHandle            savedDevice;
  220.  
  221.         GetGWorld( &savedPort, &savedDevice);
  222.         SetGWorld( (CGrafPtr)gMainWindow,  nil);
  223.         
  224.         ClipRect( clipRect ) ;
  225.         
  226.         // don't need to lockPixels on the GWorld as the 
  227.         // offscreen remains locked (see IM: QD3D), the
  228.         // pixmap for a pixmap draw context must remain locked
  229.         
  230.         CopyBits ((BitMapPtr) &theDocument->fGWorld->portPixMap,
  231.                   &gMainWindow->portBits,
  232.                   &theDocument->fGWorld->portRect, 
  233.                   &gMainWindow->portRect,
  234.                   srcCopy, 
  235.                   0L);
  236.                   
  237.         SetGWorld( savedPort, savedDevice);
  238.       }
  239. }
  240.  
  241. //--------------------------------------------------------------------------------------
  242.  
  243. OSErr WritePict( PicHandle myPic, short  dstPictFRef )
  244. {
  245.      long                    length ;
  246.     long                    dummy ;
  247.     int                        index ;
  248.     OSErr                    result ;
  249.  
  250.      // ok, myPic now contains a handle to the compressed picture
  251.                         
  252.     HLock( (Handle)(Handle)myPic);
  253.  
  254.    // set up the 512 byte header for a PICT file 
  255.     dummy = 0;
  256.     
  257.     for( index = 0; index < ( 512 / 4 ); index ++ ){
  258.         length = 4 ;
  259.            
  260.            if( (result = FSWrite(dstPictFRef, &length, &dummy)) != noErr ) {
  261.                // ErrorAlert( rErrorStrs, eCantWriteFile );
  262.             return result ;        
  263.         }
  264.     }                
  265.     
  266.        length = GetHandleSize( (Handle)myPic);
  267.       
  268.        if( (result = FSWrite(dstPictFRef, &length, *myPic)) != noErr ) {
  269.            //ErrorAlert( rErrorStrs, eCantWriteFile );
  270.         return result ;        
  271.     }
  272.  
  273.        // now get rid of the picture handle 
  274.     HUnlock( (Handle) (Handle)myPic ) ;
  275.        KillPicture(myPic);
  276.  
  277.      return noErr ;
  278. }
  279.  
  280. //--------------------------------------------------------------------------------------
  281.  
  282.  
  283. OSErr GetOutputFileRef(short    *dstPictFRef ) // GetOutputFileRefNum
  284. {
  285.     StandardFileReply    aPictSFR;    // new style Standard file record 
  286.     OSErr                result ;
  287.     SFTypeList     types = { 'PICT',0 };        // we are only interested in PICT files
  288.         
  289.     // check to see if we have the new style standard file package
  290.  
  291.     StandardPutFile( "\pSave PICT as:", "\pNew PICT", &aPictSFR);
  292.     if ( aPictSFR.sfGood  ) {
  293.         
  294.         // Delete the file of the same name, if one exits, 
  295.         // and create a new PICT file.
  296.         
  297.         FSpDelete(&aPictSFR.sfFile);
  298.         
  299.         result = FSpCreate( &aPictSFR.sfFile,'????','PICT', aPictSFR.sfScript);
  300.         if (result != noErr) {
  301.             return result;
  302.         }
  303.         
  304.         // open the data fork for writing
  305.         // ??? need to change the permissions here ???
  306.         
  307.         result = FSpOpenDF( &aPictSFR.sfFile, fsCurPerm, dstPictFRef);
  308.         if (result != noErr) {
  309.             return result;
  310.         }
  311.     }
  312.     else 
  313.         return userCanceledErr ;
  314.         
  315.     return noErr ;
  316. }
  317. //--------------------------------------------------------------------------------------
  318. PicHandle ImageToPict( DocumentPtr theDocument, WindowPtr theWindow )
  319. {
  320.     PicHandle thePicture = OpenPicture(&theDocument->fGWorld->portRect) ;
  321.     DocumentDrawOnscreen( theDocument, &theWindow->portRect) ;
  322.     ClosePicture() ;
  323.     return thePicture ;
  324. }
  325.  
  326. //--------------------------------------------------------------------------------------
  327.  
  328. void DoSaveAs(DocumentPtr theDocument) 
  329. {
  330.     short                dstPictFRef = 0;
  331.     PicHandle            myPic = nil;
  332.     OSErr                theErr;
  333.     extern gxShape         gthePicture;        // defined in BitmAp Shape with Clip.c
  334.     
  335.     // get an open a file for writing
  336.     if( (theErr = GetOutputFileRef( &dstPictFRef )) != noErr ) {
  337.         return ;
  338.     } 
  339.     else {
  340.         if(( myPic = ImageToPict ( theDocument, gMainWindow )) != nil ) {
  341.             if(WritePict( myPic, dstPictFRef ) != noErr ) {
  342.                 FSClose(dstPictFRef);
  343.                 return ;
  344.             }
  345.         }
  346.     }
  347.     
  348.     FSClose(dstPictFRef);
  349.  
  350.     return ;
  351.  
  352. }
  353. //-------------------------------------------------------------------------------------------
  354. //
  355.  
  356. short HiWrd(long aLong)
  357. {
  358.     return    (((aLong) >> 16) & 0xFFFF) ;
  359. }
  360.  
  361. //-------------------------------------------------------------------------------------------
  362. //
  363.  
  364. short LoWrd(long aLong)
  365. {
  366.     return    ((aLong) & 0xFFFF) ;
  367.  
  368. }
  369.  
  370. //-------------------------------------------------------------------------------------------
  371. //
  372.  
  373. void InitToolbox()
  374. {
  375.     Handle        menuBar = nil;
  376.  
  377.     MaxApplZone() ;
  378.     MoreMasters() ; MoreMasters() ; MoreMasters() ; 
  379.     
  380.     InitGraf( &qd.thePort );
  381.     InitFonts();
  382.     InitWindows();
  383.  
  384.     FlushEvents( everyEvent, 0 ) ;
  385.     // initialize application globals
  386.     
  387.     gQuitFlag = false;
  388.     InitCursor();
  389.     
  390. }
  391.  
  392. //-------------------------------------------------------------------------------------------
  393. //
  394. void MainEventLoop()
  395. {
  396.     EventRecord     event;
  397.     WindowPtr       window;
  398.     short           thePart;
  399.     Rect            screenRect, updateRect;
  400.     Point            aPoint = {100, 100};
  401.     
  402.  
  403.     while( !gQuitFlag )
  404.     {
  405.         if (WaitNextEvent( everyEvent, &event, 0, nil ))
  406.         {
  407.  
  408.             switch (event.what) {
  409.                 case mouseDown:
  410.                 
  411.                     thePart = FindWindow( event.where, &window );
  412.                     
  413.                     switch( thePart ) {
  414.                         case inMenuBar: 
  415.                             break;
  416.                         
  417.                         case inDrag:
  418.                     
  419.                             screenRect = (**GetGrayRgn()).rgnBBox;
  420.                             DragWindow( window, event.where, &screenRect );
  421.                             break ;
  422.                     
  423.                         case inContent:
  424.                     
  425.                             if (window != FrontWindow())
  426.                                 SelectWindow( window );
  427.                             break ;
  428.                     
  429.                         case inGoAway:
  430.                             if (TrackGoAway( window, event.where )) {
  431.                                 DoSaveAs(&gDocument) ;
  432.                                 DisposeWindow ( window );
  433.                                 gQuitFlag = true;
  434.  
  435.                             }
  436.                             break ;
  437.                             
  438.                         default:
  439.                             break ;
  440.                     }
  441.                     break ;
  442.                             
  443.                         
  444.                 case updateEvt:
  445.                 
  446.                     window = (WindowPtr)event.message;
  447.                     updateRect = (**(window->visRgn)).rgnBBox;
  448.                     SetPort( window ) ;
  449.                     BeginUpdate( window );
  450.                     DocumentDraw3DData( &gDocument ) ;
  451.                     DocumentDrawOnscreen( &gDocument, &updateRect ) ;
  452.                     EndUpdate( window );
  453.  
  454.                     break ;
  455.                     
  456.                 case keyDown:
  457.                 case autoKey:
  458.                     HandleKeyPress(&event);
  459.                     break;
  460.                     
  461.                 case diskEvt:
  462.                     if ( HiWrd(event.message) != noErr ) 
  463.                         (void) DIBadMount(aPoint, event.message);
  464.                     break;
  465.                     
  466.                 case osEvt:
  467.                 case activateEvt:
  468.                     break;
  469.  
  470.  
  471.             }
  472.         }
  473.         else {
  474.             // we received a null event, rotate the cube
  475.             TQ3Matrix4x4    tmp;
  476.             Rect        theRect = ((GrafPtr)gMainWindow)->portRect ;
  477.             
  478.             SetPort((GrafPtr)gMainWindow) ;
  479.             Q3Matrix4x4_SetRotate_XYZ(&tmp, 0.1, 0.12, 0.08);
  480.             Q3Matrix4x4_Multiply(&gDocument.fRotation, &tmp, &gDocument.fRotation);
  481.  
  482.             InvalRect( &theRect ) ;
  483.         }
  484.     }
  485. }
  486.  
  487.  
  488. //-------------------------------------------------------------------------------------------
  489. //
  490. void HandleKeyPress(EventRecord *event)
  491. {}
  492.  
  493. //-------------------------------------------------------------------------------------------
  494. //
  495.  
  496.  
  497.  
  498.